package com.wang.ymcc.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.wang.lwm.constents.MQConstants;
import com.wang.lwm.dto.RegisterCodeInRedis;
import com.wang.lwm.dto.StationInMQDto;
import com.wang.lwm.exception.GlobalException;
import com.wang.lwm.result.JSONResult;
import com.wang.lwm.util.AssertUtil;
import com.wang.lwm.util.StrUtils;
import com.wang.lwm.util.StringUtils;
import com.wang.ymcc.CourseDoc;
import com.wang.ymcc.domain.*;
import com.wang.ymcc.dto.*;
import com.wang.ymcc.feignclient.EsSearchServerFeign;
import com.wang.ymcc.feignclient.MediaServerFeign;
import com.wang.ymcc.mapper.*;
import com.wang.ymcc.service.*;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

import com.wang.ymcc.util.QRCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import springfox.documentation.spring.web.json.Json;


import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author whale
 * @since 2022-10-25
 */
@Service
@Slf4j
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    //@Autowired
    //private TeacherMapper teacherMapper;
    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private ICourseMarketService marketService;
    @Autowired
    private ICourseDetailService detailService;
    @Autowired
    private ICourseResourceService resourceService;
    @Autowired
    private ICourseSummaryService summaryService;
    @Autowired
    private ICourseTeacherService courseTeacherService;
    @Autowired
    private ICourseService courseService;
    @Autowired
    private ICourseChapterService courseChapterService;
    @Autowired
    private EsSearchServerFeign esSearchServerFeign;
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    private MediaServerFeign mediaServerFeign;

    @Override
    public String getCode(String username) {
        String key = username;
        System.out.println(key);
        String code = StrUtils.getComplexRandomString(6);
        //检查redis中是否存在验证码
        RegisterCodeInRedis codeInRedis = (RegisterCodeInRedis)redisTemplate.opsForValue().get(username);
        if(codeInRedis!=null){
            //1.检查距离上次发送的时间间隔
            if ((System.currentTimeMillis()-codeInRedis.getTime())>30*1000*60) {
                code=codeInRedis.getCode();
            }
        }
        RegisterCodeInRedis newCodeInRedis = new RegisterCodeInRedis(code,System.currentTimeMillis());
        redisTemplate.opsForValue().set(key,newCodeInRedis,30, TimeUnit.MINUTES);

        return code;
    }

    @Override
    public String erweima() throws Exception{
        // 存放在二维码中的内容
        String text = "我是小铭";
        // 嵌入二维码的图片路径
        String imgPath = "E:/erweima/Sunrise.jpg";
        // 生成的二维码的路径及名称
        String destPath = "E:/erweima/jam.jpg";
        // 生成二维码
        //QRCodeUtil.encode(text,imgPath);
        QRCodeUtil.encode(text, imgPath , destPath, true);
        // 解析二维码
        String str = QRCodeUtil.decode(destPath);
        // 打印出解析出的内容
        System.out.println(str);
        return destPath;
    }

    /*
        获取详情页数据
     */
    @Override
    public CourseDetailVo CourseDetailById(Long id) {
        //1数据的验证
        if(id.equals("")){
            new GlobalException("请勿通过地址栏请求");
        }
        //2.根据id查询course
        Course course = courseService.selectById(id);
        //3.验证课程状态数据是否存在
        if(course.getStatus()==0){
            new GlobalException("视频暂时未上架");
        }
        //4.查询营销数据 CourseMarket
        CourseMarket courseMarket = marketService.selectById(id);
        //5.查询课程详情
        CourseDetail courseDetail = detailService.selectById(id);
        //6.查询课程对应的老师
        List<Teacher> teachers = new ArrayList<>();
        List<CourseTeacher> courseTeachers = courseTeacherService.selectByCourseId(id);
        for (CourseTeacher courseTeacher : courseTeachers) {
            Teacher teacher = teacherService.selectById(courseTeacher.getId());
            teachers.add(teacher);
        }
        //7.根据课程找到对应的章节
        //找到章节
        Wrapper<CourseChapter> wrapper = new EntityWrapper<>();
        wrapper.eq("course_id",id);
        List<CourseChapter> courseChapters = courseChapterService.selectList(wrapper);
        //将章节装入到map
        Map<Long,CourseChapter> mapchapters = courseChapters.stream().collect(
                Collectors.toMap(CourseChapter::getId,CourseChapter->CourseChapter)
        );
        //获取章节下面的视频数据
        List<MediaFile> mediaServerFeign1 = mediaServerFeign.get1(id);
        //将视频数据放到章节的字段下面
        String jsonString = JSON.toJSONString(mediaServerFeign1);
        List<MediaFile> mediaFiles = JSON.parseArray(jsonString, MediaFile.class);

        List<CourseChapter> list =   new ArrayList<>();
        mediaFiles.forEach(mediaFile -> {
            mediaFile.setFileUrl("");
            CourseChapter courseChapter = mapchapters.get(mediaFile.getChapterId());
            if(courseChapter!=null){
                courseChapter.getMediaFile().add(mediaFile);
                list.add(courseChapter);
            }
        });

//        maplist.forEach(mediaFile -> {
//            mediaFile.setFileUrl("");
//            //获取
//            CourseChapter courseChapter = mapchapters.get(mediaFile.getChapterId());
//            if(courseChapter!=null) {
//                courseChapter.getMediaFile().add(mediaFile);
//                list.add(courseChapter);
//            }
//
//        });


        //8.放入结果集
        CourseDetailVo courseDetailVo = new CourseDetailVo(course,courseMarket,courseDetail,teachers,list);
        return courseDetailVo;
    }

    @Autowired
    private ICourseUserLearnService courseUserLearnService;
    @Override
    public CourseStateVo courseStateById(Long id) {
        AssertUtil.isNotNull(id,"非法的请求");
        //1.查询Course表 检查课程状态
        Course course = selectById(id);
        //2.查询营销表 课程是否免费
        CourseMarket courseMarket = marketService.selectById(id);
        //3.要用户是否购买的此课程
        //3.1 获取当前的登录用户
        Long loginId = 3L;

        Wrapper<CourseUserLearn> wrapper = new EntityWrapper<>() ;
        wrapper.eq("login_id",loginId);
        wrapper.eq("course_id",id);
        CourseUserLearn courseUserLearn = courseUserLearnService.selectOne(wrapper);
        //检查课程是否上线
        boolean isOnline = course.getStatus()==Course.STATUS_ONLINE;
        //检查课程是否免费
        boolean isFree = courseMarket.getCharge()==1;
        //用户是否购买
        boolean isBuy = courseUserLearn!=null&&courseUserLearn.getState()!=1;

        return new CourseStateVo(isFree,isOnline,isBuy);
    }

    @Autowired
    private ICourseMarketService courseMarketService;
    @Override
    public CourseOrderDaraVo info(String ids) {
        //校验
        AssertUtil.isNotEmpty(ids,"非法访问");
        //分割处理
        List<Long> longs = StrUtils.splitStr2LongArr(ids);
        //查询course
        List<Course> courses = selectBatchIds(longs);
        //查询maket
        List<CourseMarket> courseMarkets = courseMarketService.selectBatchIds(longs);
        //转换为map
        Map<Long, CourseMarket> collectmap = courseMarkets.stream().collect(Collectors.toMap(CourseMarket::getId, CourseMarket -> CourseMarket));
        //创建数据类
        List<CourseItemVo> courseItemVo = new ArrayList<>();
        //创建金额实体类
        BigDecimal bigDecimal = new BigDecimal("0");
        //将数据添加到实体类
        for (Course cours : courses) {
            CourseMarket courseMarket = collectmap.get(cours.getId());
            courseItemVo.add(new CourseItemVo(cours,courseMarket));
            bigDecimal = bigDecimal.add(courseMarket.getPrice());
        }
        return new CourseOrderDaraVo(courseItemVo,bigDecimal);
    }


    @Override
    public void save(CourseParamDto courseParamDto) {
        Course course = courseParamDto.getCourse();
        CourseDetail courseDetail = courseParamDto.getCourseDetail();
        CourseMarket courseMarket = courseParamDto.getCourseMarket();
        CourseResource courseResource = courseParamDto.getCourseResource();
        List<Long> teacherIds = courseParamDto.getTeacharIds();
        //3.保存课程表
        course.setStatus(Course.STATUS_OFFLINE);
        //TODO
        course.setLoginId(1L);
        course.setLoginUserName("zs");
        //老师名字查询
        Wrapper<Teacher> query = new EntityWrapper<>();
        // where  id  in （ 1,2）
        query.in("id",teacherIds);
        List<Teacher> teachers = teacherService.selectList(query);
        // List<Teacher> teachers -->"陈老师,赵老师"
        //映射
        String teacherNames = teachers.stream().map(teacher -> teacher.getName() ).collect(Collectors.joining(","));
        course.setTeacherNames(teacherNames);
        insert(course);
        //4.保存营销表
        courseMarket.setId(course.getId());
        marketService.insert(courseMarket);
        //5.保存详情表
        courseDetail.setId(course.getId());
        detailService.insert(courseDetail);
        //6.保存资源表
        courseResource.setCourseId(course.getId());
        resourceService.insert(courseResource);
        //7.初始化汇总表
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(course.getId());
        summaryService.insert(courseSummary);
        //8.保存老师的中间表
        teacherIds.forEach(teacherId->{
            CourseTeacher ct = new CourseTeacher();
            ct.setCourseId(course.getId());
            ct.setTeacherId(teacherId);
            courseTeacherService.insert(ct);
        });
    }

    /*课程上架 方法
       //1.根据id查找对应Course
       //2.数据校验【数据非空】
       //3.根据id查找t_courseMarket
       //4.根据id查找CourseSummary
       //5.更新Course对象状态
       //6.发起远程调用保存到es
   * */
    @Override
    public void onLineCourse(Long id) {
        //通过id获取对象
        Course course = courseService.selectById(id);
        //判断是否为非法访问
        AssertUtil.isNotNull(course,"非法访问");
        //创建es存储对象
        CourseDoc courseDoc = new CourseDoc();
        //获取相关信息表并设置付费信息
        CourseMarket courseMarket = marketService.selectById(id);
        courseDoc.setChargeName(courseMarket.getCharge()==1?"免费":"付费");
        //获取相关表信息
        CourseSummary courseSummary = summaryService.selectById(id);
        //修改基础表上传时间和状态
        course.setOnlineTime(new Date());
        course.setStatus(1);
        //更新数据库
        updateById(course);
        //数据拷贝  通过openfen调用传入es
        BeanUtils.copyProperties(courseMarket,courseDoc);
        BeanUtils.copyProperties(course,courseDoc);
        BeanUtils.copyProperties(courseSummary,courseDoc);
        esSearchServerFeign.save(courseDoc);

        //站内信发布
        sendMQ(courseDoc);
    }

    @Override
    public void offLineCourse(Long id) {
        //通过id获取对象
        Course course = courseService.selectById(id);
        course.setStatus(0);
        esSearchServerFeign.delete(course);
        updateById(course);
    }

    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    public void sendMQ(CourseDoc courseDoc) {
        List<Long> userIds = Arrays.asList(1L, 2L, 3L);
        //组装消息对象
        String content = "亲爱的用户您好，最新课程  <a href='http://course.ymcc.com:6002/detail.html?courseId=s%'> s% </a> 发布啦，点击课程了解详情";
        //content = String.format(content,courseDoc.getId(),courseDoc.getName());
        StationInMQDto dto = new StationInMQDto("课程发布啦",content,"系统消息",userIds);
        String jsonString = JSON.toJSONString(dto);
        Message<String> message = MessageBuilder.withPayload(jsonString).build();
        SendResult sendResult = rocketMQTemplate.syncSend(MQConstants.MQ_STATION_TOPIC + ":" + MQConstants.MQ_STATION_TAGS, message);
        log.info("课程站内信发布",sendResult);
    }
}
